#include "hr_sc04_driver.h"
#include "systick.h"
#include "stdio.h"
#include "buzzer_driver.h"
#include "nixie_driver.h"

extern uint32_t hr_sc04_counter;

void hr_sc04_driver_config(void)
{
    // 外设时钟使能
    rcu_periph_clock_enable(HR_SC04_ECHO_RCU_GPIO_PORT);
    rcu_periph_clock_enable(HR_SC04_TRIG_RCU_GPIO_PORT);

    // 配置触发TRIG
    gpio_mode_set(HR_SC04_TRIG_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, HR_SC04_TRIG_PIN);
    // 输出,推挽输出,
    gpio_output_options_set(HR_SC04_TRIG_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, HR_SC04_TRIG_PIN);
    // 初始低电平
    gpio_bit_reset(HR_SC04_TRIG_PORT, HR_SC04_TRIG_PIN);

    // 配置回声ECHO
    // 输入,下拉,默认低电平
    gpio_mode_set(HR_SC04_ECHO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, HR_SC04_ECHO_PIN);
}

/**
 * 触发发送
 */
void hr_sc04_driver_trigger(void)
{
    // TRIG设置高电平,持续20us,然后恢复低电平
    gpio_bit_write(HR_SC04_TRIG_PORT, HR_SC04_TRIG_PIN, SET);
    delay_1us(20);
    gpio_bit_write(HR_SC04_TRIG_PORT, HR_SC04_TRIG_PIN, RESET);
}

/**
 * 等待回声ECHO为高电平
 */
void hr_sc04_driver_wait_echo_begin()
{
    while (RESET == gpio_input_bit_get(HR_SC04_ECHO_PORT, HR_SC04_ECHO_PIN))
        ;
}

void hr_sc04_driver_wait_echo_end()
{

    while (SET == gpio_input_bit_get(HR_SC04_ECHO_PORT, HR_SC04_ECHO_PIN))
        ;
}

float hr_sc04_driver_get_distance_mine(void)
{
    hr_sc04_driver_trigger();
    hr_sc04_driver_wait_echo_begin();
    uint64_t begin = get_current_time();
    hr_sc04_driver_wait_echo_end();
    return (float)(get_current_time() - begin) / 58.0f;
}

/**
 * 利用全局变量记录时间hr_sc04_counter
 */
float hr_sc04_driver_get_distance(void)
{
    // trigger
    gpio_bit_set(HR_SC04_TRIG_PORT, HR_SC04_TRIG_PIN);
    delay_1us(20);
    gpio_bit_reset(HR_SC04_TRIG_PORT, HR_SC04_TRIG_PIN);

    // wait echo get high
    while (RESET == gpio_input_bit_get(HR_SC04_ECHO_PORT, HR_SC04_ECHO_PIN))
        ;

    // count time
    hr_sc04_counter = 0;
    while (SET == gpio_input_bit_get(HR_SC04_ECHO_PORT, HR_SC04_ECHO_PIN))
        ;

    float dis = hr_sc04_counter / 58.0f;
    if (dis > 400)
        return 400.0f;
    if (dis < 2)
        return 2.0f;
    return dis;
}

void bi(int count)
{
    int i;
    for (i = 0; i < count; i++)
    {
        buzzer_driver_vibrate_by_freq(H1);
    }
}

void hr_sc04_driver_test(void)
{
    // float distance = hr_sc04_driver_get_distance();
    float distance = hr_sc04_driver_get_distance_mine();
    printf("distance: %.2f cm\r\n", distance);
    if (distance < 3)
    {
        bi(20);
    }
    else if (distance < 5)
    {
        bi(50);
    }
    else if (distance < 10)
    {
        bi(80);
    }
    else if (distance < 20)
    {
        bi(100);
    }
    else if (distance < 40)
    {
        bi(150);
    }
    else if (distance < 50)
    {
        bi(200);
    }
    else if (distance < 60)
    {
        bi(250);
    }
    else if (distance < 70)
    {
        bi(240);
    }
    else if (distance < 80)
    {
        bi(300);
    }
    else
    {
        // bi(500);
    }

    delay_1ms(50);
}
